package com.autocar.reader.net;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Map;
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.methods.multipart.StringPart;
import org.apache.commons.httpclient.params.HttpMethodParams;

import android.util.Log;

/**
 * @author
 * @version 1.0
 * @created 2012-3-21
 */
public class ApiClient {

	public static final String HOST = "http://www.lrt.cc";
	public static final String UTF_8 = "UTF-8";
	private final static int TIMEOUT_CONNECTION = 30000;
	private final static int TIMEOUT_SOCKET = 30000;
	private final static int RETRY_TIME = 2;

	private HttpClient getHttpClient() {
		HttpClient httpClient = new HttpClient();
		httpClient.getParams().setCookiePolicy(
				CookiePolicy.BROWSER_COMPATIBILITY);
		httpClient.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
				new DefaultHttpMethodRetryHandler());
		httpClient.getHttpConnectionManager().getParams()
				.setConnectionTimeout(TIMEOUT_CONNECTION);
		httpClient.getHttpConnectionManager().getParams()
				.setSoTimeout(TIMEOUT_SOCKET);
		httpClient.getParams().setContentCharset(UTF_8);
		return httpClient;
	}

	private GetMethod getHttpGet(String url) {
		// url = URLEncoder.encode(url);
		Log.e("mg", url);
		GetMethod httpGet = new GetMethod(url);
		httpGet.getParams().setSoTimeout(TIMEOUT_SOCKET);
		httpGet.setRequestHeader("Host", HOST);
		httpGet.setRequestHeader("Connection", "Keep-Alive");
		return httpGet;
	}

	private PostMethod getHttpPost(String url) {
		Log.e("mg", url);
		PostMethod httpPost = new PostMethod(url);
		httpPost.getParams().setSoTimeout(TIMEOUT_SOCKET);
		httpPost.setRequestHeader("Host", HOST);
		httpPost.setRequestHeader("Connection", "Keep-Alive");
		return httpPost;
	}

	public String http_get(String url) {
		return http_get(url, RETRY_TIME);
	}

	/**
	 * get
	 * 
	 * @param url
	 * @throws AppException
	 */
	private String http_get(String url, int requestTime) {
		HttpClient httpClient = null;
		GetMethod httpGet = null;
		String responseBody = null;
		int time = 0;
		do {
			try {
				httpClient = getHttpClient();
				httpGet = getHttpGet(url);
				int statusCode = httpClient.executeMethod(httpGet);
				if (statusCode != HttpStatus.SC_OK) {
					break;
				}
				responseBody = httpGet.getResponseBodyAsString();
				break;
			} catch (HttpException e) {
				e.printStackTrace();
				time++;
				if (time < requestTime) {
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e1) {
					}
					continue;
				}
				break;
			} catch (IOException e) {
				e.printStackTrace();
				time++;
				if (time < requestTime) {
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e1) {
					}
					continue;
				}
				break;
			} finally {
				if (httpGet != null)
					httpGet.releaseConnection();
				httpClient = null;
			}
		} while (time < requestTime);
		return responseBody;
	}

	/**
	 * get
	 * 
	 * @param url
	 * @throws AppException
	 */
	public String http_single_get(String url) {
		HttpClient httpClient = null;
		GetMethod httpGet = null;
		String responseBody = null;
		try {
			httpClient = getHttpClient();
			httpGet = getHttpGet(url);
			int statusCode = httpClient.executeMethod(httpGet);
			if (statusCode == HttpStatus.SC_OK) {
				responseBody = httpGet.getResponseBodyAsString();
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (httpGet != null)
				httpGet.releaseConnection();
			httpClient = null;
		}
		return responseBody;
	}

	// /**
	// * @param params
	// * @throws AppException
	// */
	// public String http_single_post(String url, Map<String, Object> params) {
	// HttpClient httpClient = null;
	// PostMethod httpPost = null;
	// int length = (params == null ? 0 : params.size());
	// Part[] parts = new Part[length];
	// int i = 0;
	// if (params != null)
	// for (String name : params.keySet()) {
	// parts[i++] = new StringPart(name, String.valueOf(params
	// .get(name)), UTF_8);
	// }
	// String responseBody = null;
	// try {
	// httpClient = getHttpClient();
	// httpPost = getHttpPost(url);
	// httpPost.setRequestEntity(new MultipartRequestEntity(parts,
	// httpPost.getParams()));
	// int statusCode = httpClient.executeMethod(httpPost);
	// if (statusCode == HttpStatus.SC_OK) {
	// responseBody = httpPost.getResponseBodyAsString();
	// }
	// } catch (Exception e) {
	// e.printStackTrace();
	// } finally {
	// if (httpPost != null)
	// httpPost.releaseConnection();
	// httpClient = null;
	// }
	// return responseBody;
	// }
	// /**
	// * @param params
	// * @throws AppException
	// */
	// public String http_single_post(String url, Map<String, Object> params) {
	// HttpClient httpClient = null;
	// PostMethod httpPost = null;
	// int length = (params == null ? 0 : params.size());
	// Part[] parts = new Part[length];
	// int i = 0;
	// if (params != null)
	// for (String name : params.keySet()) {
	// parts[i++] = new StringPart(name, String.valueOf(params
	// .get(name)), UTF_8);
	// }
	// String responseBody = null;
	// try {
	// httpClient = getHttpClient();
	// httpPost = getHttpPost(url);
	// httpPost.setRequestEntity(new MultipartRequestEntity(parts,
	// httpPost.getParams()));
	// int statusCode = httpClient.executeMethod(httpPost);
	// if (statusCode == HttpStatus.SC_OK) {
	// responseBody = httpPost.getResponseBodyAsString();
	// }
	// } catch (Exception e) {
	// e.printStackTrace();
	// } finally {
	// if (httpPost != null)
	// httpPost.releaseConnection();
	// httpClient = null;
	// }
	// return responseBody;
	// }
	//
	// /**
	// * @param params
	// * @throws AppException
	// */
	// public String http_single_post(String url, Map<String, Object> params) {
	// HttpClient httpClient = null;
	// PostMethod httpPost = null;
	// int length = (params == null ? 0 : params.size());
	// Part[] parts = new Part[length];
	// int i = 0;
	// if (params != null)
	// for (String name : params.keySet()) {
	// parts[i++] = new StringPart(name, String.valueOf(params
	// .get(name)), UTF_8);
	// }
	// String responseBody = null;
	// try {
	// httpClient = getHttpClient();
	// httpPost = getHttpPost(url);
	// httpPost.setRequestEntity(new MultipartRequestEntity(parts,
	// httpPost.getParams()));
	// int statusCode = httpClient.executeMethod(httpPost);
	// if (statusCode == HttpStatus.SC_OK) {
	// responseBody = httpPost.getResponseBodyAsString();
	// }
	// } catch (Exception e) {
	// e.printStackTrace();
	// } finally {
	// if (httpPost != null)
	// httpPost.releaseConnection();
	// httpClient = null;
	// }
	// return responseBody;
	// }

	/**
	 * @param params
	 * @throws AppException
	 */
	public String http_single_post(String url, Map<String, Object> params) {
		HttpClient httpClient = null;
		PostMethod httpPost = null;
		int length = (params == null ? 0 : params.size());
		Part[] parts = new Part[length];
		int i = 0;
		if (params != null)
			for (String name : params.keySet()) {
				parts[i++] = new StringPart(name, String.valueOf(params
						.get(name)), UTF_8);
			}
		String responseBody = null;
		try {
			httpClient = getHttpClient();
			httpPost = getHttpPost(url);
			httpPost.setRequestEntity(new MultipartRequestEntity(parts,
					httpPost.getParams()));
			int statusCode = httpClient.executeMethod(httpPost);
			if (statusCode == HttpStatus.SC_OK) {
				responseBody = httpPost.getResponseBodyAsString();
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (httpPost != null)
				httpPost.releaseConnection();
			httpClient = null;
		}
		return responseBody;
	}

	/**
	 * @param params
	 * @throws AppException
	 */
	public String http_single_post(String url, Map<String, Object> params,
			Map<String, File> files) {
		HttpClient httpClient = null;
		PostMethod httpPost = null;
		int length = (params == null ? 0 : params.size())
				+ (files == null ? 0 : files.size());
		Part[] parts = new Part[length];
		int i = 0;
		if (params != null)
			for (String name : params.keySet()) {
				parts[i++] = new StringPart(name, String.valueOf(params
						.get(name)), UTF_8);
			}
		if (files != null) {
			for (String file : files.keySet()) {
				try {
					parts[i++] = new FilePart(file, files.get(file));
					Log.e("mg", "file: " + files.get(file).getAbsolutePath());
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				}
			}
		}
		String responseBody = null;
		try {
			httpClient = getHttpClient();
			httpPost = getHttpPost(url);
			httpPost.setRequestEntity(new MultipartRequestEntity(parts,
					httpPost.getParams()));
			int statusCode = httpClient.executeMethod(httpPost);
			if (statusCode == HttpStatus.SC_OK) {
				responseBody = httpPost.getResponseBodyAsString();
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (httpPost != null)
				httpPost.releaseConnection();
			httpClient = null;
		}
		return responseBody;
	}

	/**
	 * @param params
	 * @param files
	 * @throws AppException
	 */
	public String http_post(String url, Map<String, Object> params,
			Map<String, File> files) {
		HttpClient httpClient = null;
		PostMethod httpPost = null;
		int length = (params == null ? 0 : params.size())
				+ (files == null ? 0 : files.size());
		Part[] parts = new Part[length];
		int i = 0;
		if (params != null)
			for (String name : params.keySet()) {
				parts[i++] = new StringPart(name, String.valueOf(params
						.get(name)), UTF_8);
			}
		if (files != null)
			for (String file : files.keySet()) {
				try {
					parts[i++] = new FilePart(file, files.get(file));
					System.out.println(files.get(file).getAbsolutePath());
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				}
			}

		String responseBody = null;
		int time = 0;
		do {
			try {
				httpClient = getHttpClient();
				httpPost = getHttpPost(url);
				httpPost.setRequestEntity(new MultipartRequestEntity(parts,
						httpPost.getParams()));
				int statusCode = httpClient.executeMethod(httpPost);
				if (statusCode != HttpStatus.SC_OK) {
					break;
				} else if (statusCode == HttpStatus.SC_OK) {
				}
				responseBody = httpPost.getResponseBodyAsString();
				break;
			} catch (HttpException e) {
				e.printStackTrace();
				time++;
				if (time < RETRY_TIME) {
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e1) {
					}
					continue;
				}
				break;
			} catch (IOException e) {
				e.printStackTrace();
				time++;
				if (time < RETRY_TIME) {
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e1) {
					}
					continue;
				}
				break;
			} finally {
				if (httpPost != null)
					httpPost.releaseConnection();
				httpClient = null;
			}
		} while (time < 1);
		return responseBody;
	}

	/**
	 * @param imgurl
	 * @param filepath
	 */
	public String getHttpResult(String url, int time) {
		HttpURLConnection conn = null;
		try {
			URL murl = new URL(url);
			conn = (HttpURLConnection) murl.openConnection();
			conn.setRequestMethod("GET");
			conn.setConnectTimeout(time * 1000);
			conn.setReadTimeout(time * 1000);
			conn.setRequestProperty("User-Agent", "NetFox");
			conn.setRequestProperty("RANGE", "bytes=" + 0 + "-");
			InputStream inputStream = conn.getInputStream();
			StringBuffer sb = new StringBuffer();
			String line;
			BufferedReader reader = new BufferedReader(new InputStreamReader(
					inputStream, "UTF-8"));
			while ((line = reader.readLine()) != null) {
				sb.append(line);
			}
			inputStream.close();
			return sb.toString();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			if (conn != null)
				conn.disconnect();
		}
	}
}
